<?
class DbAnalyzer extends Root{

	var $ObjectClass = Array();
	var $logSql = Array();
	var $tabLimit = Array();
	var $LimRequete = Array();
	var $Module;
	var $Association=Array();
	var $ClefsRetenus=Array();
	var $CalledObjectClass=Array();
	var $Cache = Array();
	var $cacheChilds = Array();
	var $QueryTab = Array();
	var $checkRightsSuccess;
	var $tabId= Array();
	var $Order = Array();
	var $useLimits;
	var $useOrder;
	var $IndexObjectClass = Array();
	var $tabCache = Array();
	//CONFIG CACHE DEBRAYABLE
	var $liteCache = true;
	//------------------------------//
	// INITIALISATION		//
	//------------------------------//
	//Constructeur
	function DbAnalyzer($Schema,$Module) {
		$this->Module = $Module;
		$this->loadSchema($Schema);
	}

	function loadSchema($Schema) {
		//Lecture du schema et initialisation des objets
		$this->AnalizeSchema($Schema);
		//Creation des liens relatifs entre objectClass
		$this->initRelatives();
		//Creation des objet Association pour les caridnalites longues
		$this->initAssociation();
	}

	//Initialisation des liens entre ObjectClass
	function initRelatives(){
		//On initialise les references
		for ($i=0;$i<count($this->ObjectClass);$i++){
			if (sizeof($this->ObjectClass[$i]->Etrangeres))foreach ($this->ObjectClass[$i]->Etrangeres as $Key=>$ClefEtrangere){
				if (($ClefEtrangere['card'] == '1,n' || $ClefEtrangere['card'] == '0,n')&&$ClefEtrangere["Reference"]){
					$nb = sizeof($this->ObjectClass);
					$this->IndexObjectClass[$nb] = $Key;
					$this->ObjectClass[$nb]= ObjectClass::createInstance($ClefEtrangere,$this->Module);
					$this->ObjectClass[$nb]->initFromReference($ClefEtrangere,$Key);
				}
			}
		}
		for ($i=0;$i<count($this->ObjectClass);$i++){
			$this->ObjectClass[$i]->parentOf = $this->isParentOf($this->ObjectClass[$i]->titre);
			$this->ObjectClass[$i]->childOf = $this->isChildOf($this->ObjectClass[$i]->titre);
		}
	}
	//Traitement du Schï¿œma
	function AnalizeSchema($XmlResult) {
		$Pos=1;
		if (is_array($XmlResult))$XmlKeys=array_keys($XmlResult);
		//Extraction des cles du tableau associatif
		for ($i=0;$i<count($XmlKeys);$i++) {
			switch ($XmlKeys[$i]) {
				case "OBJECTCLASS":
					for ($j=0;$j<sizeof($XmlResult[$XmlKeys[$i]]);$j++) {
						$nb = sizeof($this->ObjectClass);
						$this->IndexObjectClass[$nb] = $XmlResult[$XmlKeys[$i]][$j]['@']['title'];
						$this->ObjectClass[$nb]=ObjectClass::createInstance($XmlResult[$XmlKeys[$i]][$j],$this->Module);
					}
					break;

				default:
					$GLOBALS['Systeme']->Log->log("ERREUR DE CONFIGURATION DANS LE MODULE ".$this->Nom." : Borne Inconnue ".$XmlKeys[$i]);
					break;
			}
		}
		return $Result;
	}

	//Initialisation des associations entres objectclass
	function initAssociation() {
		//Intiailisation des associations
		//Generation des associations de cardinalite superieure a 1
		// 		echo "------------------------------\r\n";
		// 		print_r($this->ObjectClass);
		if (sizeof($this->ObjectClass))foreach ($this->ObjectClass as $Objet){
			if (sizeof($Objet->childOf))foreach ($Objet->childOf as $ClefEtrangere){
				if ($ClefEtrangere['Card'] == '1,n' || $ClefEtrangere['Card'] == '0,n'){
					$this->Association[]=new Association($ClefEtrangere,$this->Module,$Objet->titre,$Objet->driver);
				}
			}
			/*			if (sizeof($Objet->parentOf))foreach ($Objet->parentOf as $ClefEtrangere){
				if (($ClefEtrangere['Card'] == '1,n' || $ClefEtrangere['Card'] == '0,n')&&$ClefEtrangere["Reference"]){
				$this->Association[]=new Association($ClefEtrangere,$this->Module,$Objet->titre,$Objet->driver);
				}
				}*/
		}
	}


	//------------------------------//
	// GESTION DU CACHE		//
	//------------------------------//
	//Chargement du cache
	function loadCache($Id){
		/*Cache SQL*/
		$Query = "Dossier/Home/".$Id."/Fichier/SQLsearch.cache";
		$Chemin = "Home/".$Id."/SQLsearch.cache";
		if (SQL_CACHE && file_exists($Chemin)) {
			$Tab = $GLOBALS["Systeme"]->Modules["Explorateur"]->callData($Query);
			$this->Cache = unserialize($Tab[0]["Contenu"]);
			return true;
		}else return false;
	}

	//Ecriture du cache
	function setCache($Cache) {
		$this->isCached=$Cache;
	}

	//Gestion du cache sur une session
	function loadLiteCache($Query){
 		if ($this->Module=="Explorateur") return false;
		if (SQL_LITE_CACHE&&$this->liteCache){
			$tabCell = urlencode($Query).$this->Order[0].$this->Order[1];
			if (is_array($this->tabCache)) if (array_key_exists($tabCell,$this->tabCache)){
				if ($this->LimRequete[0]>=$this->tabCache[$tabCell]["limitMin"]&&$this->LimRequete[1]<=$this->tabCache[$tabCell]["limitMax"]){
					//echo "<BR><b>OK</b><BR>";
					$Max = $this->LimRequete[0]+$this->LimRequete[1];
					for ($i=$this->LimRequete[0];$i<$Max;$i++){
						if (!empty($this->tabCache[$tabCell]["Results"][$i])){
							$Result[] = $this->tabCache[$tabCell]["Results"][$i];
						}
					}
				}
				return $Result;
			}else return false;
		}else return false;
	}

	//Ecriture du cache
	function writeInCache($Results,$Query){
		if ($this->Module=="Explorateur") return false;
		$tabCell = urlencode($Query).$this->Order[0].$this->Order[1];
		if (is_array($this->tabCache)) if (array_key_exists($tabCell,$this->tabCache)){
			$Old = $this->tabCache[$tabCell];
			if ($this->LimRequete[0]<$Old["limitMin"])$Replace=true;
			if ($this->LimRequete[1]>$Old["limitMax"])$Replace=true;
		}else $Replace=true;
		if ($Replace==true){
			$this->tabCache[$tabCell]["Results"] = $Results;
			$this->tabCache[$tabCell]["limitMin"] = $this->LimRequete[0];
			$this->tabCache[$tabCell]["limitMax"] = $this->LimRequete[1];
		}
	}

	//------------------------------//
	// FONCTION D EXPORTATION	//
	//------------------------------//
	//Extraction des donnï¿œes par rapport a un groupe proprietaire
	function saveGroupData($groupId){
		$Resultats = "\r\n\r\n\r\n\r\n#MODULE ".$this->Module."\r\n\r\n\r\n\r\n";
		for ($i=0;$i<count($this->ObjectClass);$i++){
			$TabSql[$this->ObjectClass[$i]->titre] = $this->ObjectClass[$i]->saveGroupData($groupId);
		}
		foreach ($TabSql as $Nom=>$Objet){
			$Resultats .= "\r\n#Contenu de la table $Nom \r\n";
			if (is_array($Objet)) foreach ($Objet as $Requete){
				$Resultats .= $Requete."\r\n";
			}else $Resultats .= "#C'est une table vide\r\n";

		}
		return $Resultats;
	}

	//Sauvegarde de la base de donnï¿œe complete
	function saveData(){
		//Cree des fichiers SQL de toute la base
		for ($i=0;$i<count($this->ObjectClass);$i++) $Result=$this->ObjectClass[$i]->saveData();
		for ($i=0;$i<count($this->Association);$i++) $Result=$this->Association[$i]->saveData();
		return ($Result!=NULL) ? 1 : 0;
	}

	//--------------------------------------//
	// FONCTIONS PUBLIQUES D INTERROGATION	//
	//--------------------------------------//
	//Retourne une reference de l objectclass definit comme master dans le schema
	function getMaster(){
		/*Renvoie l'objectclass principal d'un module*/
		foreach($this->ObjectClass as $ObjClass){
			if (!is_array($ObjClass->childOf)) return $ObjClass->titre;
			else{
				if ($ObjClass->childOf[0]["Titre"]==$ObjClass->titre && !is_array($ObjClass->childOf[1])) return $ObjClass->titre;
			}
		}
	}

	//retourne un tableau recapitulant les objectClass enfants de $type
	function isParentOf($type){
		//Cette fonction permet de connaitre les objets pour lesquelles $type est une clef etrangere, et qui sont par consequent ses enfants.
		$ite=0;
		for ($i=0;$i<sizeof($this->ObjectClass);$i++){
			//on recherche $type dans tout les objets, a l'aide de la propriete data.
			foreach ($this->ObjectClass[$i]->Etrangeres as $Key=>$Etrangere){
				$Data=explode(',',$Etrangere['data']);
				$Data=$Data[0];
				$Type=$type;
				if ($Data == $Type){
					$Results[$ite]['Titre'] = $this->ObjectClass[$i]->titre;
					$Results[$ite]['Heritage'] = $this->ObjectClass[$i]->Heritage;
					$Results[$ite]['Reference'] = $this->ObjectClass[$i]->Reference;
					$Results[$ite]['Icon'] = $this->ObjectClass[$i]->Icon;
;					$Results[$ite]['Driver'] = $this->ObjectClass[$i]->driver;
					$Results[$ite]['Id'] = $i;
					$Results[$ite]['Nom'] = $Key;
					$Results[$ite]['Card'] = $Etrangere['card'];
					$Results[$ite]['Behaviour'] = $Etrangere['behaviour'];
					$Results[$ite]['associated'] = $Etrangere['associated'];
					$Results[$ite]['hidden'] = $Etrangere['hidden'];
					$Results[$ite]['container'] = $Etrangere['container'];
;					$Results[$ite]['closed'] = $Etrangere['closed'];
					$Results[$ite]['Action'] = $Etrangere['action'];
					$Results[$ite]['data'] = $Etrangere['data'];
					$Results[$ite]['search'] = $Etrangere['search'];
					$Results[$ite]['Target'] = $Etrangere['Target'];
					$Results[$ite]['Default'] = $Etrangere['default'];
					$Results[$ite]['FKey'] = $Key;
					$Results[$ite]['Description'] = $Etrangere['description'];
					if (empty($Results[$ite]['Description']))
					  $Results[$ite]['Description'] = $this->ObjectClass[$i]->Description;
					switch ($Results[$ite]['Card']) {
						case "0,1":
						case "1,1":
							if ($this->ObjectClass[$i]->titre==$Etrangere['Objet']){
								//C recursif
								$Results[$ite]['Table'] = $this->ObjectClass[$i]->titre;
								$Results[$ite]['Champ'] = $Key;
							}else{
								//C une cle simple
								$Results[$ite]['Table'] = $Etrangere['Objet'];
								$Results[$ite]['Champ'] = $Key;
							}
							break;
						case "0,n":
						case "1,n":
							if ($this->ObjectClass[$i]->titre==$Etrangere['Objet']){
								//C recursif
								$Results[$ite]['Table'] = $Key;
								$Results[$ite]['Champ'] = $this->ObjectClass[$i]->titre."Id";
							}else{
								$Results[$ite]['Table'] = $this->ObjectClass[$i]->titre.$Key;
								$Results[$ite]['Champ'] = $this->ObjectClass[$i]->titre;
							}
							break;
					}
					$ite++;
				}
			}
		}
		return $Results;
	}

	//retourne un tableau recapitulant les objectClass qui sont les parents de $type
	function isChildOf($type){
		//Cette fonction permet de connaitre les objets parents de $type, en analysant le parametre data des clefs secondaires.
		$ite=0;
		$i=$this->findByTitle($type);
		if (is_array($this->ObjectClass[$i]->Etrangeres))foreach ($this->ObjectClass[$i]->Etrangeres as $Key=>$Etrangere){
			$Data=explode(',',$Etrangere['data']);
			$j=$this->findByTitle($Data[0]);
			$Results[$ite]['Titre'] = $Data[0];
			$Results[$ite]['Id'] = $this->findByTitle($Data[0]);
			$Results[$ite]['Card'] = $Etrangere['card'];
			$Results[$ite]['Behaviour'] = $Etrangere['behaviour'];
			$Results[$ite]['associated'] = $Etrangere['associated'];
			$Results[$ite]['hidden'] = $Etrangere['hidden'];
			$Results[$ite]['closed'] = $Etrangere['closed'];
			$Results[$ite]['container'] = $Etrangere['container'];
			$Results[$ite]['data'] = $Etrangere['data'];
			$Results[$ite]['Heritage'] = $this->ObjectClass[$i]->Heritage;
			$Results[$ite]['Reference'] = $this->ObjectClass[$i]->Reference;
			$Results[$ite]['Driver'] = $this->ObjectClass[$i]->driver;
			$Results[$ite]['Icon'] = $this->ObjectClass[$j]->Icon;
			$Results[$ite]['Champ'] = $Key;
			$Results[$ite]['FKey'] = $Key;
			$Results[$ite]['search'] = $Etrangere['search'];
			$Results[$ite]['Nom'] = $Key;
			$Results[$ite]['Target'] = $Etrangere['Target'];
			$Results[$ite]['Default'] = $Etrangere['default'];
			$Results[$ite]['Description'] = $Etrangere['description'];
			if (empty($Results[$ite]['Description']))
				$Results[$ite]['Description'] = $this->ObjectClass[$Results[$ite]['Id']]->Description;
			switch ($Results[$ite]['Card']) {
				case "0,1":
				case "1,1":
					if ($this->ObjectClass[$i]->titre==$Etrangere['Objet']){
						//C recursif
						$Results[$ite]['Table'] = $Etrangere['Objet'];
					}else{
						//C une cle simple
						$Results[$ite]['Table'] = $this->ObjectClass[$i]->titre;
					}
					break;
				case "0,n":
				case "1,n":
					if ($this->ObjectClass[$i]->titre==$Etrangere['Objet']){
						//C recursif
						$Results[$ite]['Table'] = $Key;
						$Results[$ite]['Champ'] = $Data[0].$Results[$ite]['Champ'];
					}else{
						$Results[$ite]['Table'] = $this->ObjectClass[$i]->titre.$Results[$ite]['Champ'];
					}
					break;
			}
			$ite++;
		}
		return $Results;
	}

	//Retourne un tableau recapitulatif
	function RecapTab(){
		for ($i=0;$i<count($this->ObjectClass);$i++){
			$Tab[$i]["driver"] = $this->ObjectClass[$i]->driver;
			$Tab[$i]["titre"] =  $this->ObjectClass[$i]->titre;
			$Tab[$i]["Module"] =  $this->Module;
			$Tab[$i]["Master"] =  $this->ObjectClass[$i]->Master;
			$Tab[$i]["Prefix"] =  $this->ObjectClass[$i]->Prefix;
			$Tab[$i]["Heritage"] =  $this->ObjectClass[$i]->Heritage;
			$Tab[$i]["AccessPoint"] =  $this->ObjectClass[$i]->AccessPoint;
		}
		return $Tab;
	}


	function getRights($Ids){
		$Num = $this->findByTitle("Droit");
		$Results = $this->ObjectClass[$Num]->getRights($Ids);
		return $Results;
	}


	/*Fonction qui donne le numero de l'objet en echange de son nom.*/
	function findByTitle($titre){
		$result = array_search($titre,$this->IndexObjectClass);
		if (is_int($result)) return $result;
		for ($i=0; $i<count($this->ObjectClass); $i++)
		{
			if (is_array($this->ObjectClass[$i]->ReferChilds))
			{
				foreach ($this->ObjectClass[$i]->ReferChilds as $Ref)
				{
					if ($titre == $Ref["Titre"]) return "REF";
				}
			}
		}
		return "-1";
	}
	/*Fonction qui donne le numero de l'objet en echange de son nom.*/
	function getByTitle($titre){
		$result = array_search($titre,$this->IndexObjectClass);
		//if (is_int($result)) return $result;
		return $this->ObjectClass[$result];
	}
	function getByTitleOrFkey($Element)
	{
		/* 1 : C'est un objectclass
		 * 2 : C'est un objectclass mais avec >1 associations, avec $j l'association
		 * -1 : Ca ne correspond a rien
		 */
		//if ($Element="") return -1;
		$Obj = $this->findByTitle($Element);
		if ($Obj!=-1) return Array("Type"=>1,"Nom"=>$Element,"Num"=>$Obj);

		for ($i=0;$i<count($this->ObjectClass);$i++){
			foreach($this->ObjectClass[$i]->Etrangeres as $Name => $E){
				if ($Element==$Name) return Array("Type"=>2,"Nom"=>$E["Objet"],"Fkey" =>$Element);
			}
		}
		return Array("Type"=>-1,"Nom"=>"");
	}

	function isReflexive($Obj){
		$Id = $this->findByTitle($Obj);
		if ($Id==-1) return;
		return $this->ObjectClass[$Id]->isReflexive();
	}
	
	//Recuperation de l'objectClass definit par defaut
	function getDefaultObjectClass($N=1){
		for ($i=0;$i<sizeof($this->ObjectClass);$i++){
			if ($this->ObjectClass[$i]->Default) return $this->ObjectClass[$i]->titre;
		}
		return false;
	}
	//----------------------------------------------//
	// VERIFICATION DES DONNEES			//
	//----------------------------------------------//
	//Fonction de verification
	function Check(){
		//Lance une verification de la bdd.
		echo "<li>OBJECTCLASS</li><ul>";
		for ($i=0;$i<count($this->ObjectClass);$i++) {
			echo "<li>OBJECTCLASS ".$this->ObjectClass[$i]->titre."</li><ul>";
			$this->ObjectClass[$i]->Check();
			echo "</ul>";
		}
		echo "</ul>";
		echo "<li>ASSOCIATION</li><ul>";
		for ($i=0;$i<count($this->Association);$i++) $this->Association[$i]->Check();
		echo "</ul>";
		return 1;
	}

	//----------------------------------------------//
	// FONCTIONS PUBLIQUES DE RECHERCHE/INSERTION	//
	//----------------------------------------------//

	//Fonction d insertion
	function Query($Entree){
		//		$this->tabCache = NULL;
		if(is_object($Entree)){
			$i=$this->findByTitle($Entree->ObjectType);
			$Object = $this->ObjectClass[$i]->Insert($Entree);
			$Object["ObjectType"] = $Entree->ObjectType;
		}
		return $Object;
	}


	/*Cette fonction appelle son homonyme dans ObjectClass pr obtenir un resultat en recherche floue, ou bien appelle getChilds ou getParents si l'url le permet.
	 Parametre: la recherche(string).
	 Renvoi: un tableau*/
	function searchObject($Tab,$Etape='',$Offset='',$Limit='',$Query="",$Otype="",$Ovar="",$Select="",$GroupBy=""){
		//Modification des limites selon le type de recherche
		// 		echo "------AV-------> $Offset  | $Limit \r\n";
// 				echo "EXECUTION REQUETE ---".$this->Module."/$Query - $Type \r\n";
		switch ($Tab[0]["Type"]) {
			case "Direct":
				// 				echo "REQUETE DIRECTE !!! 0|1\r\n";
				$Offset = 0;
				$Limit = 1;
				break;
		}
		// 		echo "-------AP------> $Offset  | $Limit \r\n";
		//Recherche des champs de type order
		$this->checkRightsQuery = false;
		unset($this->LimRequete);
		$this->LimRequete[0] = $Offset;
		$this->LimRequete[1] = $Limit;
		unset($this->Order);
		$this->Order[0] = $Ovar;
		$this->Order[1] = $Otype;
		//Gestion du cache
		if (SQL_CACHE) {
			$QTemp = urlencode($Query."_".$Offset."_".$Limit);
			$QTemp = str_replace("%","_",$QTemp);
			if (empty($this->Cache[$QTemp]) && $this->isCached) {
				$this->Cache[$QTemp]=$this->lookForObject($Tab,$Etape,0,$Query,$Select,$GroupBy);
				if (empty($this->Cache[$QTemp])) $this->Cache[$QTemp]="NORESULT";
			}elseif(!$this->isCached){
				return $this->lookForObject($Tab,0,array(),$Query,"",$GroupBy);
			}
			if ($this->Cache[$QTemp]=="NORESULT") return "";
			return $this->Cache[$QTemp];
		}else{
			$Cache = $this->loadLiteCache($Query);
			if (!$Cache){
				$Results = $this->lookForObject($Tab,0,array(),$Query,$Select,$GroupBy);
				return $Results;
			}else{
				// 			echo "UTILISATION DU CACHE \r\n";
				// 			print_r($Cache);
				return $Cache;
			}
		}
	}


	//----------------------------------------------//
	// FONCTIONS PRIVEES DE RECHERCHE/INSERTION	//
	//----------------------------------------------//
	//Fonction privï¿œe recursive paermettant d'analyser la requete tableau
	function lookForObject($Tab,$NbEtape='',$Analyse="",$Query="",$Select="",$GroupBy=""){
		$Num = $this->findByTitle($Tab[$NbEtape]['DataSource']);
// 		print_r($Tab);
		if ($Num==-1){return false;}
		//On teste la valeur de la paire en cours
		if ($Tab[$NbEtape]['Value']==''){
			//Si il n y pas de paire suivante 
			if (is_array($Tab[$NbEtape+1])){
				$Parent = true;
				$Temp = $this->ObjectClass[$Num]->getKeyInfo($Tab[$NbEtape+1]['DataSource'],$Tab[$NbEtape]['Value'],true);
				//il s agit d une recherche de parents
				$Num2 = $this->findByTitle($Tab[$NbEtape+1]['DataSource']);
				if ($Temp['Driver']!=$this->ObjectClass[$Num2]->driver){
					$Results = $this->ObjectClass[$Num2]->Search('',$Tab[$NbEtape+1]['Value'],false,"Id",$GroupBy);
					$Results = $this->ObjectClass[$Num]->Search('',$Results[0][$Temp['Champ']],false,$Select,$GroupBy);
				}else{
					$Results = $this->ObjectClass[$Num]->Search($Temp,$Tab[$NbEtape+1]['Value'],true,$Select,$GroupBy);
				}
			}else{
				//alors il s agit d'une recherche d enfants
				if (!$NbEtape){
					//Sans contraintes
					$Results = $this->ObjectClass[$Num]->Search($Analyse[$NbEtape-1],$Tab[$NbEtape]['Value'],false,$Select,$GroupBy);
				}else{
					//Le cas de pilote different
					if ($Analyse[$NbEtape-1]['Driver']!=$this->ObjectClass[$Num]->driver){
						$Num2 = $this->findByTitle($Tab[$NbEtape-1]['DataSource']);
						$Results = $this->ObjectClass[$Num2]->Search('',$Tab[$NbEtape-1]['Value'],false,"Id",$GroupBy);
						$Results = $this->ObjectClass[$Num]->Search('',$Analyse[$NbEtape-1]['Champ']."=".$Results[0]["Id"],false,$Select,$GroupBy);
					}else{
						$Results = $this->ObjectClass[$Num]->Search($Analyse[$NbEtape-1],$Tab[$NbEtape]['Value'],false,$Select,$GroupBy);
					}
				}
			}
		}else{
			//Il s agit d'une recherche paramï¿œtrï¿œe
			if  (is_array($Tab[$NbEtape+1])) {
				//Il y a une paire suivante donc il s agit d une recherche complexe
				$Temp = $this->ObjectClass[$Num]->getKeyInfo($Tab[$NbEtape+1]['DataSource'],$Tab[$NbEtape]['Value']);
				if ($Temp) $Analyse[] = $Temp; else return false;
				$Results = $this->lookForObject($Tab,$NbEtape+1,$Analyse,"",$Select,$GroupBy);
				return $Results;
			}else{
				//Le cas de pilote different
				if ($NbEtape>0&&$Analyse[$NbEtape-1]['Driver']!=$this->ObjectClass[$Num]->driver){
					$Num2 = $this->findByTitle($Tab[$NbEtape-1]['DataSource']);
					$Results = $this->ObjectClass[$Num2]->Search('',$Tab[$NbEtape-1]['Value'],false,"Id",$GroupBy);
					$Results = $this->ObjectClass[$Num]->Search('',$Analyse[$NbEtape-1]['Champ']."=".$Results[0]["Id"],false,$Select,$GroupBy);
				}else{
					$Results =  $this->ObjectClass[$Num]->Search($Analyse[$NbEtape-1],$Tab[$NbEtape]['Value'],false,$Select,$GroupBy);
				}
			}
		}
		//----------------------------------------------//
		//Gestion des Historiques	 		//
		//----------------------------------------------//
		if (is_array($Results)){
			$nbR=sizeof($Results);
			for($i=0;$i<$nbR;$i++){
				if (!$Parent)$Results[$i]["ObjectType"] = $Tab[sizeof($Tab)-1]['DataSource'];
				for ($j=0;$j<sizeof($Tab)-1;$j++){
					if ($Tab[$j]['Value']!='') 
						$Results[$i]["Historique"][] = Array(
							"Id" => $Tab[$j]['Value'],
							"ObjectType" => $Tab[$j]['DataSource']
						);
				}
			}
		}
		if (!empty($Query)&&!$Select) $this->writeInCache($Results,$Query);
		return $Results;
	}

	//Recuperation des objectclass relative a une autre
	// 	function getRelatives($ObjClassOther,$ObjClassMain,$id,$TypeSearch,$Analyse){
	// 		//Fonction qui verifie et transmet les recherches de proches a l'objectclass.
	// 		$i=$this->findByTitle($ObjClassMain);
	// 		$j=$this->findByTitle($ObjClassOther);
	// 		$tabFKey = ($TypeSearch=='c') ? $this->ObjectClass[$j]->parentOf : $this->ObjectClass[$j]->childOf;
	// 		//Si il y a bien une possibilite de famille, on verifie le lien.
	// 		if (is_array($tabFKey)){
	// 			foreach ($tabFKey as $Clef){
	// 				if ($Clef['Titre']==$ObjClassMain){
	// 					$Data=$this->ObjectClass[$i]->getRelatives($id,$TypeSearch,$ObjClassOther,$Clef['Card'],$Analyse);
	//
	// 				}
	// 			}
	// 		}
	// 		return (is_array($Data)) ? $Data : false;
	// 	}


	//----------------------------------------------//
	// FONCTIONS FERMETURE DE CONNEXION		//
	//----------------------------------------------//

	function close() {
		//Fermeture de la base de donnee
		//ON desactive le cache pour linstant .....
		if (SQL_CACHE&&$this->Module=="Systeme"){
			$Obj = new genericClass("Explorateur");
			$Obj->initFromType("Fichier");
			$Obj->Set("Url","Dossier/Home/".$GLOBALS["Systeme"]->User->Id);
			$Obj->Set("Nom","SQLsearch.cache");
			$Obj->Set("Contenu",serialize($this->Cache));
			$Obj->Save();
		}
		//On transfere les fichiers a transferer
		if (is_array($this->Mouvements)){
			foreach ($this->Mouvements as $Deplace){
				$Fichier  = $Deplace["Depart"].$Deplace["Fichier"];
				$Destination = $Deplace["Depart"].$Deplace["Fin"].$Deplace["Fichier"];
				if (!file_exists($Fichier)) continue 1;
				if (!@copy($Fichier,$Destination)){
					$Erreur = "Impossible de copier un fichier";
					$GLOBALS["Systeme"]->Log->log($Erreur,$Fichier);
				}else{
					if (@!unlink($Fichier)){
						$Erreur = "Impossible de supprimer un fichier";
						$GLOBALS["Systeme"]->Log->log($Erreur,$Fichier);
					}
				}
			}
		}
	}

	//----------------------------------------------//
	// FONCTIONS INTERROGATION DE SCHEMA		//
	//----------------------------------------------//
	//renvoie la liste des accesspoint ou un accesspoint en particulier si le parametre est renseignï¿œ
	function AccessPoint($Name=""){
		if ($Name=="") {
			foreach ($this->ObjectClass as $Obj) {
				if ($Obj->AccessPoint) $Result[] = $Obj;
			}
		}else{
			foreach ($this->ObjectClass as $Obj) {
				if ($Obj->titre==$Name&&$Obj->AccessPoint) $Result[] = $Obj;
			}
		}
		return $Result;
	}
	//renvoie la liste des accesspoint ou un accesspoint en particulier si le parametre est renseignï¿œ
	function Dico($Name=""){
		if ($Name=="") {
			foreach ($this->ObjectClass as $Obj) {
				if ($Obj->Dico) $Result[] = $Obj;
			}
		}else{
			foreach ($this->ObjectClass as $Obj) {
				if ($Obj->titre==$Name&&$Obj->Dico) $Result[] = $Obj;
			}
		}
		return $Result;
	}
}
?>
